package br.ufmg.ubicomp.droidguide.eventservice;

import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

import android.app.ListActivity;
import android.content.Intent;
import android.graphics.Color;
import android.os.Bundle;
import android.os.Handler;
import android.util.Log;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
import android.widget.AdapterView;
import android.widget.ArrayAdapter;
import android.widget.AdapterView.OnItemClickListener;
import br.ufmg.ubicomp.droidguide.R;
import br.ufmg.ubicomp.droidguide.common.DroidGuideConfigurationManager;
import br.ufmg.ubicomp.droidguide.common.DroidGuideConstants;
import br.ufmg.ubicomp.droidguide.communication.ServiceCommunicationService;
import br.ufmg.ubicomp.droidguide.eventservice.notification.DGNotification;
import br.ufmg.ubicomp.droidguide.eventservice.notification.DGNotificationType;
import br.ufmg.ubicomp.droidguide.eventservice.notification.NotificationBucket;
import br.ufmg.ubicomp.droidguide.utils.AndroidUtils;

public class ServiceList extends ListActivity {

	Collection<DroidGuideRemoteService> services = null;
	Collection<DroidGuideRemoteService> subscribedServices = null;
	private List<Integer> serviceColors = new ArrayList<Integer>();
	private List<String> serviceKeys = new ArrayList<String>();
	private List<String> serviceNames = new ArrayList<String>();
	private List<Boolean> serviceSubscribed = new ArrayList<Boolean>();
	private static final int COLOR_OFF = Color.BLACK;
	private static final int COLOR_ON = Color.RED;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		// TODO Auto-generated method stub
		super.onCreate(savedInstanceState);
        // Use an existing ListAdapter that will map an array
        // of strings to TextViews
		
		// get list of services in server
		String dgKey = DroidGuideConfigurationManager.getInstance().getData(
				DroidGuideConstants.DROID_GUIDE_USER_KEY);
		try {
			
			services = ServiceCommunicationService.getListOfServices();			
			NotificationBucket.getInstance().add(new DGNotification(DGNotificationType.APPLICATION, System.currentTimeMillis(), 
					"Services available: " + services.size(), "ServiceList"));
			
			subscribedServices = ServiceCommunicationService.getSubscribedServices(dgKey);
			NotificationBucket.getInstance().add(new DGNotification(DGNotificationType.APPLICATION, System.currentTimeMillis(), 
					"Subscribed services: " + subscribedServices.size(), "ServiceList"));
			
		} catch (Exception e) {
			e.printStackTrace();
			notifyError(e, "ListServices");
		}

		int i = 0;
		for (DroidGuideRemoteService s: services)
		{
			// if this service has been subscribed
			if (isServiceSubscribedByUser(s))
			{
				serviceColors.add(COLOR_ON);
				serviceSubscribed.add(Boolean.TRUE);
			} else
			{
				serviceColors.add(Color.LTGRAY);
				serviceSubscribed.add(Boolean.FALSE);
			}
			serviceKeys.add(s.getKey());
			serviceNames.add(s.getDescription());
			i++;
		}

        setListAdapter(new ArrayAdapter<String>(this,
                android.R.layout.simple_list_item_1, serviceNames
                ));
        
        //getListView().setItemsCanFocus(true);
        //getListView().setBackgroundColor(Color.LTGRAY);
        getListView().setOnItemClickListener(new OnItemClickListener(){

			public void onItemClick(AdapterView<?> arg0, View arg1, int arg2,
					long id) {
				
				handleMarkedItem(id);
			}
        	
        });
        getListView().setTextFilterEnabled(true);
        // selecting subscribed services
        
        updateSubscribedServicesToUI();               
	}

	private void updateSubscribedServicesToUI() {
		Thread task = new Thread(){
        	@Override
        	public void run() {
                for (int i = 0; i < serviceColors.size(); i++)
                {
                	if (serviceColors.get(i).equals(COLOR_ON))
                	{
                		setBackgroundColorOfChild(i, COLOR_ON);
                	}
                }
        	}
        };
        
        AndroidUtils.runTask(task, 1000);
	}

	private boolean isServiceSubscribedByUser(DroidGuideRemoteService s) {
		boolean isSubscribed = subscribedServices != null && subscribedServices.contains(s);
		if (isSubscribed)
		{
			Log.i("ServiceList", "found a subscribed service: " + s.getDescription());
		}
		return isSubscribed;
	}
	
    public boolean onCreateOptionsMenu(Menu menu) {
        super.onCreateOptionsMenu(menu);

        menu.add(0,0, 0, "Ok").setIcon(R.drawable.ic_ok)
		 .setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS));
        menu.add(0,1, 0, "Refresh").setIcon(R.drawable.ic_refresh)
		 .setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS));
        menu.add(0,1, 0, "Cancel").setIcon(R.drawable.ic_cancel)
		 .setIntent(new Intent(android.provider.Settings.ACTION_SETTINGS));
      return true;
    }

	@Override
    public boolean onOptionsItemSelected(MenuItem item){
    	Intent i;
    	int numSubServices = 0;
    	int numUnsubServices = 0;
    	if (item.getItemId() == 0) // OK
    	{
    		// subscribe to services
    		Collection<String> servicesToSubscribe = new ArrayList<String>();
    		Collection<String> servicesToUnsubscribe = new ArrayList<String>();
    		try {
				String dgKey = DroidGuideConfigurationManager.getInstance().getData(
						DroidGuideConstants.DROID_GUIDE_USER_KEY);

				for (int j = 0; j < serviceColors.size(); j++)
				{
					int color = serviceColors.get(j);
					// if the service has been selected
					if (color == COLOR_ON && !serviceSubscribed.get(j))
					{
						servicesToSubscribe.add(serviceKeys.get(j));
					} else if (color == COLOR_OFF && serviceSubscribed.get(j))
					{
						servicesToUnsubscribe.add(serviceKeys.get(j));
					}
				}
				
				numSubServices = subscribeServices(numSubServices,
						servicesToSubscribe, dgKey);
				
				numUnsubServices = unsubscribeToServices(numUnsubServices,
						servicesToUnsubscribe, dgKey);
				
				Log.i("ServiceList", "subscribed services: " + numSubServices);
				Log.i("ServiceList", "unsubscribed services: " + numUnsubServices);
				
				if (numSubServices > 0)
				{
					AndroidUtils.showNotification(this, "Services", "Subscription to "+numSubServices+" services successful.", DGNotificationType.INCOMMING, "Subscription");
				}
				if (numUnsubServices > 0)
				{
					AndroidUtils.showNotification(this, "Services", "Unsubscription to "+numUnsubServices+" services successful.", DGNotificationType.INCOMMING, "Unsubscription");
				}
				
			} catch (Exception e) {
				e.printStackTrace();
				notifyError(e, "SubscribeToServices");
			}
    	} else if (item.getItemId() == 1) // refresh
    	{
            updateItemColorsBasedOnSelection();		
    	}
    	if (item.getItemId() == 0 || item.getItemId() == 2)
    	{
    		finish();
    	}
    	
        return true;
    }

	private void updateItemColorsBasedOnSelection() {
		for (int j = 0; j < serviceColors.size(); j++)
		{
			if (serviceColors.get(j).equals(COLOR_ON))
			{
				setBackgroundColorOfChild(j, COLOR_ON);
			}
		}
	}

	private int unsubscribeToServices(int numUnsubServices,
			Collection<String> servicesToUnsubscribe, String dgKey)
			throws Exception {
		for (String serviceKey: servicesToUnsubscribe)
		{
			ServiceCommunicationService.unsubscribeToService(serviceKey, dgKey);
			numUnsubServices++;
		}
		return numUnsubServices;
	}

	private int subscribeServices(int numSubServices,
			Collection<String> servicesToSubscribe, String dgKey)
			throws Exception {
		for (String serviceKey: servicesToSubscribe)
		{
			ServiceCommunicationService.subscribeToService(serviceKey, dgKey);
			numSubServices ++;
		}
		return numSubServices;
	}



	private void notifyError(Exception e, String op) {
		NotificationBucket.getInstance().add(new DGNotification(DGNotificationType.ERROR, System.currentTimeMillis(), 
				op + ": "+ e.getMessage(), "ServiceList"));
		AndroidUtils.showAlert(this, "An error ocurred.");
	}
    
    
	private void handleMarkedItem(long id)
	{
		String service = serviceNames.get((int) id);
		System.out.println(getListView().getChildCount());
		if (serviceColors.get((int) id) == COLOR_ON){
			setBackgroundColorOfChild(id, COLOR_OFF);
			AndroidUtils.showAlert(this, "service " + service + " unmarked");
			AndroidUtils.showNotification(this, "Services", service + " removed from favorites.", DGNotificationType.OUTGOING, "Services");
		} else 
		{
			setBackgroundColorOfChild(id, COLOR_ON);
			AndroidUtils.showAlert(this, "service " + service + " marked");
			AndroidUtils.showNotification(this, "Services", service + " added to favorites.", DGNotificationType.OUTGOING, "Services");
		} 
	}

	private void setBackgroundColorOfChild(long id, int color) {
		View child = getListView().getChildAt((int) id);
		child.setBackgroundColor(color);
		serviceColors.set((int) id, color);
	}
	
}
